package com.damai.utils;

import java.lang.reflect.Method;

import com.citywithincity.reflect.CtClassUtil;
import com.citywithincity.utils.StringUtils;

import javassist.CannotCompileException;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;

public class CtMethodBuilder {

	CtClassBuilder ctClassBuilder;

	
	private CtMethod method;
	
	private StringBuilder sb;
	
	CtMethodBuilder(CtClassBuilder ctClassBuilder) {
		this.ctClassBuilder = ctClassBuilder;
		sb= new StringBuilder("{\n");
	}
	
	public CtMethodBuilder setMethod(Method method) throws NotFoundException{
		Class<?>[] types = method.getParameterTypes();
		
		CtClass returnType = ctClassBuilder.pool.get(method.getReturnType().getName());
		this.method = new CtMethod(returnType, method.getName(), CtClassUtil.toCtClassTypes(types), ctClassBuilder.getClazz());
		return this;
	}
	
	//
	public CtMethodBuilder fieldEq(String name){
		sb.append(name).append("=").append("").append(";\n");
		return this;
	}
	
	/**
	 * 类似
	 * String str = Utils.getString();
	 * @param type
	 * @param name
	 * @param staticClass
	 * @param staticMethod
	 * @return
	 */
	public CtMethodBuilder varEq(Class<?> type,String name,Class<?> staticClass,String staticMethod){
		sb.append(type.getName()).append(" ").append(name).append("=").append(staticClass.getName()).append(".").append(staticMethod).append("()").append(";\n");//.append("=").append("").append(";\n");
		return this;
	}
	
	/**
	 * 类似 str=Utils.getString();
	 * @param name
	 * @param staticClass
	 * @param staticMethod
	 * @return
	 */
	public CtMethodBuilder eqCallStatic(Class<?> staticClass,String staticMethod){
		sb.append(localName).append("=").append(staticClass.getName()).append(".").append(staticMethod).append("()").append(";\n");//.append("=").append("").append(";\n");
		return this;
	}
	
	public CtMethodBuilder eqCallStatic(Class<?> staticClass,String staticMethod,String... args){
		sb.append(localName).append("=").append(staticClass.getName()).append(".")
		.append(staticMethod).append("(");
		
		sb.append(StringUtils.join(args));
		
		sb.append(")").append(";\n");//.append("=").append("").append(";\n");
		return this;
	}
	
	public CtMethodBuilder call(String method){
		sb.append(localName).append(".").append(method).append("();\n");
		return this;
	}
	
	public CtMethodBuilder call(String method,String... args){
		sb.append(localName).append(".").append(method).append("(").append(StringUtils.join(args)).append(");\n");
		return this;
	}
	
	/**
	 * 类似 some.method();
	 * @param name
	 * @param method
	 * @return
	 */
	public CtMethodBuilder setter(String setterName,String arg){
		sb.append(localName).append(".").append(setterName).append("(")
		.append(arg).append(");\n");
		return this;
	}
	
	private String localName;
	
	public CtMethodBuilder var(Class<?> type,String name){
		localName = name;
		sb.append(type.getName()).append(" ").append(name).append(";\n");//.append("=").append("").append(";\n");
		return this;
	}
	public CtMethodBuilder varNew(Class<?> type,String name){
		localName = name;
		sb.append(type.getName()).append(" ").append(name).append("=").append("new ").append(type.getName())
		.append("()").append(";\n");//.append("=").append("").append(";\n");
		return this;
	}
	
	public CtMethodBuilder setBody(String src) throws CannotCompileException{
		this.method.setBody(new StringBuilder().append("{").append(src).append("}").toString());
		return this;
	}

	public void build() throws CannotCompileException {
		sb.append("}");
		this.method.setBody(sb.toString());
	}

	public CtMethod getMethod() {
		// TODO Auto-generated method stub
		return method;
	}

	public CtMethodBuilder returnBoolean(boolean value) {
		sb.append("return ");
		if(value){
			sb.append("java.lang.Boolean.TRUE;\n");
		}else{
			sb.append("java.lang.Boolean.FALSE;\n");
		}
		return this;
	}
	
	
}
